﻿Imports System.Windows.Forms
Imports System.Text.RegularExpressions

Public Class TextBoxPersonalizado
    Inherits TextBox

    Private iTipoTexto As eTipoTexto

    Public Enum eTipoTexto
        Normal = 0
        Alfanumerico = 1
        Numerico = 2
        Valor = 3
        CPF = 4
        CNPJ = 5
        Data = 6
        Telefone = 7
        TelefoneDDD = 8
        CEP = 9
    End Enum

    Public ReadOnly Property EmailValido() As Boolean
        Get
            Dim strRegex As String = "^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}" + "\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\" + ".)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$"
            Dim re As Regex = New Regex(strRegex)
            If (re.IsMatch(MyBase.Text)) Then
                Return (True)
            Else
                Return (False)
            End If
        End Get
    End Property

    <System.ComponentModel.Category("Courier"), System.ComponentModel.Description("Determina qual o tipo do texto que pode ser inserido no componente")> _
    Public Property TipoTexto() As eTipoTexto
        Get
            Return Me.iTipoTexto
        End Get
        Set(ByVal Value As eTipoTexto)
            Me.iTipoTexto = Value
        End Set
    End Property

    Protected Overrides Sub OnLostFocus(ByVal e As System.EventArgs)

        Select Case Me.TipoTexto

            Case eTipoTexto.CPF
                If Not IsNumeric(MyBase.Text) AndAlso Verificador.ValidaCPF(MyBase.Text) Then
                    MyBase.Text = 0
                End If
                MyBase.Text = MyBase.Text.Replace(".", "").Replace(",", "").Replace("/", "").Replace("-", "")
                MyBase.Text = String.Format("{0:000\.000\.000\-00}", Convert.ToDouble(MyBase.Text))

            Case eTipoTexto.CNPJ
                MyBase.Text = MyBase.Text.Replace(".", "").Replace(",", "").Replace("/", "").Replace("-", "")
                If Not IsNumeric(MyBase.Text) AndAlso Verificador.ValidaCNPJ(MyBase.Text) Then
                    MyBase.Text = 0
                End If
                MyBase.Text = String.Format("{0:00\.000\.000\/0000\-00}", Convert.ToDouble(MyBase.Text))

            Case eTipoTexto.Valor
                If Not IsNumeric(MyBase.Text) Then
                    MyBase.Text = 0
                End If
                MyBase.Text = Format(Convert.ToDouble(MyBase.Text), "#,##0.00")

            Case eTipoTexto.Data
                If Not IsDate(MyBase.Text) Then
                    MyBase.Text = ""
                Else
                    MyBase.Text = MyBase.ToString("dd/MM/yyyy")
                End If
            Case eTipoTexto.Telefone
                If MyBase.Text <> String.Empty Then
                    MyBase.Text = String.Format("{0:0000\-0000}", Convert.ToDouble(MyBase.Text))
                End If

            Case eTipoTexto.TelefoneDDD
                If MyBase.Text <> String.Empty Then
                    MyBase.Text = String.Format("{0:(00)0000\-0000}", Convert.ToDouble(MyBase.Text))
                End If

            Case eTipoTexto.CEP
                If MyBase.Text <> String.Empty Then
                    MyBase.Text = String.Format("{0:00000\-000}", Convert.ToDouble(MyBase.Text))
                End If

        End Select

        MyBase.OnLostFocus(e)
    End Sub

    Protected Overrides Sub OnGotFocus(ByVal e As System.EventArgs)
        MyBase.SelectAll()
        MyBase.OnGotFocus(e)
    End Sub


    Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)

        ' Verifica qual o tipo de texto que o componente está configurado para aceitar.
        Select Case Me.TipoTexto
            Case eTipoTexto.Alfanumerico
                e.Handled = Not (IsNumeric(e.KeyChar) OrElse (e.KeyChar Like "[A-Z]" OrElse e.KeyChar Like "[a-z]"))
            Case eTipoTexto.Numerico, eTipoTexto.CPF, eTipoTexto.CNPJ, eTipoTexto.CEP, eTipoTexto.Telefone, eTipoTexto.TelefoneDDD
                e.Handled = Not (IsNumeric(e.KeyChar))
            Case eTipoTexto.Normal
                e.Handled = False
            Case eTipoTexto.Valor
                e.Handled = Not (IsNumeric(e.KeyChar) OrElse
                                e.KeyChar = "." OrElse e.KeyChar = ",")
        End Select

        ' Verifica se a tecla pressionada é o "Backspace", pois ela sempre estará habilitada
        If e.KeyChar = Chr(System.Windows.Forms.Keys.Back) Or e.KeyChar = Chr(System.Windows.Forms.Keys.ControlKey) Then
            e.Handled = False
        End If

        ' Dispara o evento KeyPress para que o usuário possa dele utilizar-se
        MyBase.OnKeyPress(e)

    End Sub

    Protected Overrides Sub OnKeyDown(ByVal e As System.Windows.Forms.KeyEventArgs)
        Dim isControlPressed As Boolean = (Control.ModifierKeys And Keys.Control) <> 0

        Select Case e.KeyCode
            Case Keys.Enter
                'SendKeys.SendWait("{TAB}")
            Case Keys.C
                If isControlPressed Then
                    MyBase.Copy()
                End If
            Case Keys.V
                If isControlPressed Then
                    MyBase.Paste()
                End If
            Case Keys.X
                If isControlPressed Then
                    MyBase.Cut()
                End If
            Case Keys.Z
                If isControlPressed Then
                    MyBase.Undo()
                End If
        End Select

        MyBase.OnKeyDown(e)

    End Sub
End Class